package impl

import (
	"encoding/base64"
	"github.com/gin-gonic/gin"
	"github.com/jonasngs/go_entry_task/http_server/global"
	"github.com/jonasngs/go_entry_task/http_server/user"
	"github.com/jonasngs/go_entry_task/protobuf3/pb"
	"io/ioutil"
	"log"
	"net/http"
	"path/filepath"
)

type ManagementImpl struct {
}

// LoginHandler Handler to load login page
func (m ManagementImpl) LoginHandler(ctx *gin.Context) {
	sessionToken, err := ctx.Cookie("session-id")
	if err != nil {
		log.Printf("No user session found: %v\n", err)
		ctx.HTML(http.StatusOK, "login.html", gin.H{})
		return
	}
	_, err = global.GrpcUserManagerClient.LoadProfile(ctx, &pb.ProfileRequest{SessionToken: sessionToken})
	if err != nil {
		ctx.HTML(http.StatusOK, "login.html", gin.H{})
		return
	}
	ctx.Redirect(http.StatusFound, "/profile")
}

// ProfileHandler Handler to load profile page
func (m ManagementImpl) ProfileHandler(ctx *gin.Context) {
	sessionToken, err := ctx.Cookie("session-id")
	if err != nil {
		log.Printf("No user session found: %v\n", err)
		ctx.Redirect(http.StatusFound, "/login")
		return
	}
	//fmt.Println(session_token)
	res, err := global.GrpcUserManagerClient.LoadProfile(ctx, &pb.ProfileRequest{SessionToken: sessionToken})
	if err != nil {
		ctx.Redirect(http.StatusFound, "/login")
		return
	}
	ctx.HTML(http.StatusOK, "profile.html", gin.H{
		"Nickname":       res.User.Nickname,
		"profilePicture": res.User.ProfilePicture,
		"Username":       res.User.Username,
	})
}

// UpdateHandler Handler to load edit page
func (m ManagementImpl) UpdateHandler(ctx *gin.Context) {
	sessionToken, err := ctx.Cookie("session-id")
	if err != nil {
		log.Printf("No user session found: %v\n", err)
		ctx.Redirect(http.StatusFound, "/login")
		return
	}
	res, err := global.GrpcUserManagerClient.LoadProfile(ctx, &pb.ProfileRequest{SessionToken: sessionToken})
	if err != nil {
		ctx.JSON(http.StatusUnauthorized, gin.H{
			"error":   "",
			"message": "",
		})
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"nickName":       res.User.Nickname,
		"profilePicture": res.User.ProfilePicture,
	})

}

// LoginRequestHandler Handler for login post request
func (m ManagementImpl) LoginRequestHandler(ctx *gin.Context) {
	username := ctx.PostForm("username")
	password := ctx.PostForm("password")
	if password == "" || username == "" {
		ctx.JSON(http.StatusUnauthorized, gin.H{
			"message": "401",
			"method":  "用户名或密码为空",
		})
		return
	}
	res, err := global.GrpcUserManagerClient.Login(ctx, &pb.LoginRequest{Username: username, Password: password})
	if err != nil {
		log.Printf("global.GrpcUserManagerClient invok error: %v\n", err)
		ctx.JSON(http.StatusUnauthorized, gin.H{
			"message": "401",
			"method":  "用户名或密码错误",
		})
		return
	}
	if res.SessionToken != "" {
		ctx.SetCookie("session-id", res.SessionToken, 360, "/", "localhost", false, true) //maxAge parameter in seconds
	}
	ctx.Redirect(http.StatusFound, "/profile")
	// if res.GetRc().String() == "Success" {
	// 	if res.SessionToken != "" {
	// 		ctx.SetCookie("session-id", res.SessionToken, 360, "/", "localhost", false, true) //maxAge parameter in seconds
	// 	}
	// 	ctx.Redirect(http.StatusFound, "/profile")
	// 	return
	// } else {
	// 	ctx.HTML(http.StatusForbidden, "login.html", gin.H{
	// 		"res": "Incorrect Username/Password",
	// 	})
	// 	return
	// }

}

// UpdateRequestHandler Handler for update post request
func (m ManagementImpl) UpdateRequestHandler(ctx *gin.Context) {
	sessionToken, err := ctx.Cookie("session-id")
	if err != nil {
		log.Printf("No user session found: %v\n", err)
		ctx.Redirect(http.StatusFound, "/login")
		return
	}
	image := &pb.Image{
		FileExtension: "",
		Data:          "",
	}
	nickname := ctx.PostForm("nickname")
	imageFile, err := ctx.FormFile("image_profile")
	if err == nil {
		fileExt := filepath.Ext(imageFile.Filename) //file extension
		file, err := imageFile.Open()
		if err != nil {
			log.Printf("Could not open image file: %v\n", err)
			ctx.Redirect(http.StatusFound, "/edit")
			return
		}
		imageData, _ := ioutil.ReadAll(file)
		defer file.Close()
		encodedImageBytes := base64.StdEncoding.EncodeToString(imageData) // this is without base64 encoding header
		image.FileExtension = fileExt
		image.Data = encodedImageBytes
	} else {
		log.Printf("No image file found: %v\n", err)
	}

	_, err = global.GrpcUserManagerClient.Update(ctx, &pb.UpdateRequest{Nickname: nickname, ProfilePicture: image, SessionToken: sessionToken})
	if err != nil {
		// Improve error handling
		ctx.HTML(http.StatusFound, "login.html", gin.H{})
		return
	}
	ctx.Redirect(http.StatusFound, "/profile")
}

func init() {
	user.InjectManager(new(ManagementImpl))
}
